跳到主要内容

Kubernetes 是什么

Kubernetes 是一个开源容器编排平台,可自动部署、管理和扩展应用。

官网有 中文文档,所以这里依旧只介绍 Kubernetes 的重要概念

相似的产品

主流的容器管理调度平台有三个,分别是 Docker Swarm、Mesos Marathon 和 Kubernetes

Swarm 是 Docker 公司自己的产品,会直接调度 Docker 容器,并且使用标准的 Docker API 语义,为用户提供无缝衔接的使用体验。 Swarm 更多的是面向于开发者,而且对容错性支持不够好。

Mesos 是一个分布式资源管理平台,提供了 Framework 注册机制。接入的框架必须有一个 Framework Scheduler 模块负责框架内部的任务调度,还有一个 Framework Executor 负责启动运行框架内的任务。Mesos 采用了双层调度架构,首先 Mesos 将资源分配给框架,然后每个框架使用自己的调度器将资源分配给内部的各个任务使用,比如 Marathon 就是这样的一个框架,主要负责为容器工作负载提供扩展、自我修复等功能。

Kubernetes 的组成

Kubernetes 采用了 Pod 和 Label 这样的概念,把容器组合成一个个相互依赖的逻辑单元,相关容器被组合成 Pod 后被共同部署和调度,就形成了服务,这也是 Kuberentes 和其他两个调度管理系统最大的区别。

Kubernetes 集群由各种节点组成,这些节点被分成以下两种类型:

我们需要注意 Master 和 Node 两个概念。其中 Master 是控制节点,部署着 Kubernetes 的控制面,负责整个集群的管理和控制。Node 为计算节点,或者叫作工作负载节点,每个 Node 上都会运行一些负载容器。

  • 主节点(Master),用于整个集群系统的管理控制
  • 工作节点(Node),用于运行用户实际部署的应用

每个节点上都会安装不同的组件。

最小的部署单元 Pod

Pod 是最小的部署单元,可包含多个容器,是连接在一起的容器组合并 共享文件卷。Pod 里面可以运行单个容器或者运行多个需要协同工作的容器。(所以容器不是最小单位,Pod 才是最小的调度单位)

而 Pod 又运行在一个 Worker Node 中,这个 Worker Node 可以是物理机,也可以是虚拟机。

一个 Worker Node 中可能会有很多个 Pod 同时运行,而多个 Pod 可以协同工作。

提示

比如你运行一个操作系统发行版的软件仓库,一个 Nginx 容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。

在 Pod 中,有一个容器叫 Pause,这个是当前 pod 中所有容器的父容器,也叫基础容器。这个 Pause 负责 Pod 中的容器的健康检查。

如果我们在 Pod 中部署两个容器,分别叫 Container1 和 Container2。那么 Container1 和 Container2 就会共享 pause 容器的网络栈,他们之间的通讯就会更快。

主节点 Master

每个集群必须至少有一个主节点(Master),它是控制平面的核心,负责集群的决策。这个 Kubernetes 的控制平面由三个主要组件组成,即 kube-apiserver、kube-scheduler 和 kube-controller-manager,这些组件被称为 Kubernetes 的三大件。

APIServer 的作用

它是整个 Kubernetes 集群的“灵魂”,是信息的汇聚中枢,提供了所有内部和外部的 API 请求操作的唯一入口。同时也负责整个集群的认证、授权、访问控制、服务发现等能力。

用户可以通过命令行工具 kubectl 和 APIServer 进行交互,从而实现对集群中进行各种资源的增删改查等操作。APIServer 会将所有的改动持久到 Etcd 中,同时也保存着一份内存拷贝。

这也是为什么我们希望 Master 节点可以性能好、资源规格大,尤其是当集群规模很大的时候,APIServer 的吞吐量以及占用的 CPU 和内存都要很大。APIServer 还提供很多可扩展的能力,方便增强自己的功能。

ContollerManager

它负责维护整个 Kubernetes 集群的状态,比如多副本创建、滚动更新等。

这个 Kube-controller-manager 并不是一个单一组件,内部包含了一组资源控制器,在启动的时候,会通过 goroutine 拉起多个资源控制器。这些控制器的逻辑仅依赖于当前状态,因为在分布式系统中没办法保证全局状态的同步。

同时在实现的时候避免使用过于复杂的状态机,因此每个控制器仅仅对自己对应的资源对象做操作。而且控制器做了很多容错处理,比如增加 retry 机制等。

Scheduler

它的工作简单来说就是监听未调度的 Pod,按照预定的调度策略绑定到满足条件的节点上。这个工作虽说看起来是三大件中最简单的,但是做的事情可一点不少。

Node 工作节点

集群的数据平面,负责为容器提供运行环境,即真正工作的节点,一般来说 Node 节点上会运行以下组件。

  • Kubelet:负责维护 Pod 的生命周期,比如创建和删除 Pod 对应的容器。同时也负责存储和网络的管理。一般会配合 CSI、CNI 插件一起工作。
  • KubeProxy:主要负责 Kubernetes 内部的服务通信,在主机上维护网络规则并提供转发及负载均衡能力。
  • 容器运行时:主要负责容器的镜像管理以及容器创建及运行。大家都知道的 Docker 就是很常用的容器,此外还有 Kata、Frakti 等。只要符合 CRI(Container Runtime Interface,容器运行时接口) 规范的运行时,都可以在 Kubernetes 中使用。不过最新的 K8s 废除了内置的 Docker CRI,会将这部分代码(dockershim)独立出来,使用者可独立配置。具体看 https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

整体如下所示:

除了上述这些核心组件外,通常我们还会在 Kubernetes 集群中部署一些 Add-on 组件,常见的有:

  • CoreDNS 负责为整个集群提供 DNS 服务;
  • Ingress Controller 为服务提供外网接入能力;
  • Dashboard 提供 GUI 可视化界面;
  • Fluentd + Elasticsearch 为集群提供日志采集、存储与查询等能力。

Master 和 Node 的交互方式

Kubernetes 中所有的状态都是采用上报的方式实现的。APIServer 不会主动跟 Kubelet 建立请求链接,所有的容器状态汇报都是由 Kubelet 主动向 APIServer 发起的。

当集群资源不足的时候,可以按需增加Node 节点。一旦启动 Kubelet 进程以后,它会主动向 APIServer 注册自己,这是 Kubernetes 推荐的 Node 管理方式(也可以在Kubelet 启动参数中去掉自动注册的功能,不过一般都是默认开启这个模式的)

一旦新增的 Node 被 APIServer 纳管进来后,Kubelet 进程就会定时向 APIServer 汇报 “心跳”,即汇报自身的状态,包括自身健康状态、负载数据统计等。当一段时间内心跳包没有更新,那么此时 kube-controller-manager 就会将其标记为 NodeLost(失联)。

Kubernetes 中各个组件都是以 APIServer 为中心,通过松耦合的方式进行。借助声明式 API,各部件通过 watch 的机制就可以根据各个对象的变化,很快地做出相应的处理操作。

提示

声明式 API:声明式操作在分布式系统中的好处是稳定,不怕丢操作或运行多次,例如设置副本数为 3 的操作运行多次也还是一个结果,而给副本数加 1 的操作就不是声明式的,运行多次结果就错了。

各个组件调用关系示例 ⭐

下面,以部署一个 Nginx 服务来说明 kubernetes 系统各个组件调用关系:

1、首先要明确,一旦 Kubernetes 环境启动之后,master 和 node 都会将自身的信息存储到 etcd 数据库中

2、一个 Nginx 服务的安装请求会首先被发送到 Master 节点的 ApiServer 组件

3、ApiServer 组件会调用 Scheduler 组件来决定到底应该把这个服务安装到哪个 Node 节点上,在此时,它会从 etcd 中读取各个 node 节点的信息,然后按照一定的算法进行选择,并将结果告知 ApiServer

4、ApiServer 调用 ControllerManager 去调度 Node 节点安装 Nginx 服务

5、kubelet 接收到指令后,会通知 docker,然后由 docker 来启动一个 Nginx 的 pod,这个 pod 是 kubernetes 的最小操作单元,容器必须跑在 pod 中

6、至此,一个 Nginx 服务就运行了,如果需要访问 Nginx,就需要通过 kubeProxy 来对 pod 产生访问的代理

这样,外界用户就可以访问集群中的 Nginx 服务了

Kubernetes 的分层设计

核心层:Kubernetes 最核心的功能,对外提供 API 构建高层的应用,对内提供插件式应用执行环境

应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS 解析等)

管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态 Provision 等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy 等)

接口层:kubectl 命令行工具、客户端 SDK 以及集群联邦

生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴

  • Kubernetes 外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS 应用、ChatOps 等
  • Kubernetes 内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

References